home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
t-bcinfo.zip
/
TI643.ZIP
/
TI643.ASC
Wrap
Text File
|
1992-02-25
|
6KB
|
265 lines
PRODUCT : Borland C NUMBER : 643
VERSION : All
OS : PC DOS
DATE : February 25, 1992 PAGE : 1/4
TITLE : Using a Dynamically Allocated Stack in C
/*[]------------------------------------------------------------[]*/
/*| |*/
/*| 'Using a LARGE temporary stack in a small program' |*/
/*| |*/
/*| |*/
/*| Copyright (c) 1991 by Borland International |*/
/*| All Rights Reserved. |*/
/*| |*/
/*[]------------------------------------------------------------[]*/
/************************************************************************
NOTE: If you want to use the stack-checking code in Turbo C++ or
Borland C++ then you must be in the LARGE or HUGE memory model.
**********************************************************************/
/*
The theory here is the stack checking option generates the
following code at the beginning of every function that was compiled
with it on:
_function proc far
push bp
mov bp, sp
cmp word ptr DGROUP:_stklen, sp
ja short @1@74
call far ptr F_OVERFLOW@
@1@74:
. ; the rest of the function...
.
.
This is basically checking SP against the stack length and if SP ever
becomes greater than _stklen, (which can only happen if you use all
the stack space and then wrap SP from seg:0000 to seg:FFFE) then the
overflow function gets called.
All we are doing is allocating a 66K buffer from farmalloc,
normalizing the pointer to get a full segment, saving the old values
for ss, sp, and _stklen, setting the new values, and calling the
stack-hungry function.
PRODUCT : Borland C NUMBER : 643
VERSION : All
OS : PC DOS
DATE : February 25, 1992 PAGE : 2/4
TITLE : Using a Dynamically Allocated Stack in C
This can be very useful for qsort() programs that wish to sort
very large tables, and don't need 64k of stack all the time.
If you don't use stack checking then you can use this trick from any
model.
*/
#if !defined (__LARGE__)
#error Must be in the LARGE model!
#endif
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
#include <conio.h>
unsigned _stklen = 2048; // stack = 2k
unsigned int goober = 0;
char *p;
void recurse1 (void)
{
goober++;
cprintf ("\rCalling recurse1() %u ", goober);
recurse1 ();
}
void do_reg (void)
{
recurse1 ();
}
void do_alloc (void)
{
// NOTE: these all MUST be static (or global) because if they were local
// the compiler wouldn't be able to access them after we switch
// our stacks.
static char far *p;
PRODUCT : Borland C NUMBER : 643
VERSION : All
OS : PC DOS
DATE : February 25, 1992 PAGE : 3/4
TITLE : Using a Dynamically Allocated Stack in C
static unsigned old_ss, old_sp, old_stklen;
if ((p = farmalloc (66000L)) == NULL)
{
printf ("\nNo room to allocate stack buffer!\n");
exit (1);
}
/*
We now have a pointer xxxx:0004. This example will overwrite the
bottom and top of the segment. To prevent serious memory
corruption, we must allocate a full 64K segment and normalize it
ourselves. Now if we corrupt memory at xxxx:0000 or xxxx:FFFF we are
still within the buffer we allocated, and thus are safe. This
saves us from incurring the overhead of having a HUGE pointer for
the address of our buffer.
*/
(long)p += 0x00010000; // increment segment
p -= 4; // set offset to zero
// p is now = (xxxx + 1):0000
old_ss = _SS; // save old values
old_sp = _SP;
old_stklen = _stklen;
_stklen = 60000U; // change the stack length (for checking)
_SS = FP_SEG (p); // set up our new stack segment
_SP = FP_OFF (&(p[_stklen])); // set the stack to the top
goober = 0; // reset our counter
recurse1(); // call the recursive DEATH function
// If we were to get to this point...
_SS = old_ss; // reset the values
_SP = old_sp;
_stklen = old_stklen;
(long)p -= (0x00010000 - 4);
// set the pointer back to what it was to free it
PRODUCT : Borland C NUMBER : 643
VERSION : All
OS : PC DOS
DATE : February 25, 1992 PAGE : 4/4
TITLE : Using a Dynamically Allocated Stack in C
free ((void *) p);
}
int main (void)
{
cputs ("\n\rBIG Stack Example (c) 1991 by Borland International\r\n");
// do_reg(); // call this function to compare with regular stack
do_alloc (); // call this one to allocate a BIG temporary stack
return 0;
}